package net.wy.commons.util;

import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.channels.FileChannel;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.imageio.ImageIO;

import net.wy.util.image.ImageSizer;
import net.wy.util.image.ImageUtils;

import org.apache.commons.lang.StringUtils;
import org.codehaus.jackson.map.ObjectMapper;

public class ToolUtil {
	
	/**
	 * 格式化时间
	 * @param date
	 * @return
	 */
	public static String formatDate(Date date){
		return ToolUtil.formatDate(date, "yyyy-MM-dd HH:mm:ss");
	}
	
	/**
	 * 格式化时间
	 * @param date
	 * @param pattern
	 * @return
	 */
	public static String formatDate(Date date, String pattern){
		date = date == null ? new Date() : date;
		pattern = StringUtils.isBlank(pattern) ? "yyyy-MM-dd HH:mm:ss" : pattern;
		return new SimpleDateFormat(pattern).format(date);
	}
	
	/**
	 * join by ',' to String
	 * @param ids
	 * @return
	 */
	public static String join(List<Long> ids){
		if(ids == null || ids.isEmpty()){
			return null;
		}
		StringBuffer buffer = new StringBuffer();
		for(Long id : ids){
			buffer.append(id).append(",");
		}
		String result = buffer.toString().trim();
		if(result.endsWith(",")){
			result = result.substring(0, result.length() -1);
		}
		return result;
	}
	
	/**
	 * 输入一个字符串统计该字符串某个字符的个数
	 * @param word
	 * @param reg
	 * @return
	 */
	public static int statWord(String word, String reg) {
		if(StringUtils.isBlank(word) || StringUtils.isBlank(reg)){
			return 0;
		}
		Matcher m = Pattern.compile(reg).matcher(word);
		int count = 0;// 记录个数
		while (m.find()) {
			count++;
		}
		return count;
	} 

	/**
	 * 将List转换成字符串（中间方法），将集合中的“[”、“]”转换成“(”、“)”
	 * @param list 传递入的列表
	 * @return 字符串
	 */
	public static String replace(List<Long> list){
		if(list.isEmpty()){
			return "(null)";
		}
		String strList = list.toString();
		strList = strList.replace('[', '(');
		strList = strList.replace(']', ')');
		return strList;
	}
	
	/**
	 * 获得传入时间一段时间后的时间（如果传入负数，则为时间前）
	 * @param beginTime 开始时间
	 * @param between 间隔时间
	 * @param type 类型  1-秒 2-分 3-小时 4-天
	 * @return 加减后的时间
	 */
	public static Date addTime(Date beginTime, int between, int type){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(beginTime);
		switch(type){	
		case 1 :
			calendar.add(Calendar.SECOND, between);
			break;
			
		case 2 :
			calendar.add(Calendar.MINUTE, between);
			break;
			
		case 3 :
			calendar.add(Calendar.HOUR_OF_DAY, between);
			break;
			
		case 4 :
			calendar.add(Calendar.DAY_OF_YEAR, between);
			break;
		}
		Date date = calendar.getTime();
		return date;
	}
	
	/**
	 * int[天, 时, 分, 秒]
	 * @param between 秒
	 * @return int[天, 时, 分, 秒]
	 */
	public static int[] countdown(long between){
		if(0 > between){
			return new int[]{0, 0, 0, 0};
		}
		int day = (int)(between / (24*60*60));
		int hour = (int)(((between / (60*60)) - day*24));
		int min = (int)(((between / 60) - day*24*60 - hour*60));
		int sec = (int)((between - day*24*60*60 - hour*60*60 - min*60));
        return new int[]{day, hour, min, sec};
	}
	
	/**
	 * int[时, 分, 秒]
	 * @param between 秒
	 * @return int[时, 分, 秒]
	 */
	public static int[] countdownNoDay(long between){
		if(0 > between){
			return new int[]{0, 0, 0};
		}
		int hour = (int)(((between / (60*60))));
		int min = (int)(((between / 60) - hour*60));
		int sec = (int)((between - hour*60*60 - min*60));
        return new int[]{hour, min, sec};
	}
	
    /**
     * 去掉集合中的重复值（Long）
     * @param list 传入的带有重复值的集合
     * @return 没有重复值的集合
     */
    public static List<Long> removeRepeat(List<Long> list){
    	if(list.isEmpty()){
    		return new ArrayList<Long>();
    	}
    	return new ArrayList<Long>(new LinkedHashSet<Long>(list));
    }
    
    /**
     * 去掉集合中的重复值（String）
     * @param list 传入的带有重复值的集合
     * @return 没有重复值的集合
     */
    public static List<String> removeRepeatString(List<String> list){
    	if(list.isEmpty()){
    		return new ArrayList<String>();
    	}
    	return new ArrayList<String>(new LinkedHashSet<String>(list));
    }
    
    /**
     * 将比赛类型的字符串拆分成字符数组
     * @param oldString
     * @return
     */
    public static String replaceForRaceType(String oldString){
		if(null == oldString || "".equals(oldString.trim())){
			return oldString;
		}
		String[] regexArr = {"," , "；" , ";" , "、" ,"。" ,  "\\."};
		String newString = oldString;
		for(int i=0; i<regexArr.length; i++){
			newString = newString.replaceAll(regexArr[i], "，");
		}
		return newString;
	}
    
    /**
	 * 将二进制数组转换成16进制（大写）
	 * @param array
	 * @return
	 */
	public static String byte2hex(byte[] array) {
		if (array == null || array.length == 0) {
			return null;
		}
		
		StringBuffer stringBuffer = new StringBuffer();
		for (byte num : array) {
			String temp = Integer.toHexString(num & 0xFF);
			if (temp.length() < 2) {
				stringBuffer.append(0);
			}
			stringBuffer.append(temp);
		}
		return stringBuffer.toString().toUpperCase();
	}
	
	/**
	 * 将流数据转为字符串
	 * @param stream 流数据
	 * @return
	 */
	public static String stream2String(InputStream stream){
		if(stream == null){
			return null;
		}
		try{
			StringBuffer temp = new StringBuffer();
			String line;
			BufferedReader reader = new BufferedReader(new InputStreamReader(stream, "UTF-8"));
			while ((line = reader.readLine()) != null) {
				temp.append(line).append("\n");
			}
			return temp.toString().trim();
		} catch (IOException e){
			return null;
		} finally{
			try {
				stream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 将JSON格式数据转化为Map
	 * @param data
	 * @return
	 */
	public static Map<?,?> json2map(String data){
		ObjectMapper mapper = new ObjectMapper();
		try {
			Map<?, ?> map = mapper.readValue(data, Map.class);
			return map;
		} catch (Exception e) {
			return null;
		}
	}
	
	/**
	 * 去掉Map中空的值
	 * @param map
	 * @return
	 */
	public static Map<String, String> trimMap(Map<String, String> map){
		List<String> keys = new ArrayList<String>();
		Set<Map.Entry<String, String>> set = map.entrySet();
        for (Iterator<Map.Entry<String, String>> it = set.iterator(); it.hasNext();) {
            Map.Entry<String, String> entry = (Map.Entry<String, String>) it.next();
            if(StringUtils.isBlank(entry.getValue())){
            	//遍历过程中不允许remove否则报错java.util.ConcurrentModificationException
            	//map.remove(entry.getKey());
            	keys.add(entry.getKey());
            }
        }
        for(String key : keys){
        	map.remove(key);
        }
		return map;
	}
	
	/**
	 * 将结果集排序（由高到低）
	 * @param stat
	 * @return
	 */
	public static LinkedHashMap<String, Object> sortIntegerMap(Map<String, Object> statMap){
		List<Entry<String, Object>> list = new ArrayList<Entry<String, Object>>(statMap.entrySet());
		Collections.sort(list, new Comparator<Map.Entry<String, Object>>() {
			public int compare(Map.Entry<String, Object> o1, Map.Entry<String, Object> o2) {
				double d = (Integer)o2.getValue() - (Integer)o1.getValue();
				int result = d > 0 ? 1 : (d < 0 ? -1 : 0);
				return result;
			}
		});
		
		LinkedHashMap<String, Object> sortStat = new LinkedHashMap<String, Object>();
		for (int i=0, size=list.size(); i<size; i++) {
			Entry<String, Object> e = list.get(i);
			String key = e.getKey();
			Object value = ((Integer)e.getValue()).intValue();
			sortStat.put(key, value);
		}
		return sortStat;
	}
	
	/**
	 * 将结果集排序（由高到低）
	 * @param stat
	 * @return
	 */
	public static LinkedHashMap<String, Object> sortDoubleMap(Map<String, Object> statMap){
		List<Entry<String, Object>> list = new ArrayList<Entry<String, Object>>(statMap.entrySet());
		Collections.sort(list, new Comparator<Map.Entry<String, Object>>() {
			public int compare(Map.Entry<String, Object> o1, Map.Entry<String, Object> o2) {
				double d = (Double)o2.getValue() - (Double)o1.getValue();
				int result = d > 0d ? 1 : (d < 0d ? -1 : 0);
				return result;
			}
		});
		
		LinkedHashMap<String, Object> sortStat = new LinkedHashMap<String, Object>();
		for (int i=0, size=list.size(); i<size; i++) {
			Entry<String, Object> e = list.get(i);
			String key = e.getKey();
			Object value = ((Double)e.getValue()).intValue();
			sortStat.put(key, value);
		}
		return sortStat;
	}
	
    /**
     * 剪切图片
     * @param x
     * @param y
     * @param width
     * @param height
     * @param widths
     * @param imagePath 图片路径
     * @param savePath 保存路径
     * @param diskPath 硬盘路径
     * @param saveName 保存名字（不含后缀）
     * @return 尺寸-url
     */
    public static Map<String, String> cut(int x, int y, int width, int height, int[] widths, String imagePath, String savePath, String diskPath, String saveName) {
    	Map<String, String> ret = new HashMap<String, String>();;
		
    	File headDirectory = new File( diskPath + savePath);
    	if( !headDirectory.exists() ) headDirectory.mkdirs();
    		
		File source = new File(diskPath+imagePath);
		
		if( !source.exists() )return null;
		
		String fileName =  imagePath;
		String suffix =  fileName.substring(fileName.lastIndexOf("."));
		fileName = saveName + suffix;
		String cutSourceName = fileName.replace(".", "_orz.");
    	File cutSource = new File( diskPath + savePath + cutSourceName);
		
		try {
			BufferedImage buff = ImageIO.read(source);
			buff = ImageUtils.cropImage(buff, x, y, width, height);
			ImageIO.write(buff, suffix.substring(1), cutSource);
			//ret.add(savePath + cutSourceName);

			for (int w : widths) {
				String tempName = fileName.replace(".", "_" + w + ".");
				File temp = new File(diskPath + savePath + tempName);
				ImageSizer.resize(cutSource, temp, w, 1);
				ret.put(""+w, savePath+tempName);
			}
		} catch (Exception e) {
			return null;
		}
		
		File orgFile = new File(diskPath + savePath +  fileName.replace(".", "_org."));
		
		if( !source.getPath().equals(orgFile.getPath()) ){
			FileInputStream fi = null;
			FileOutputStream fo = null;
			FileChannel in = null;
			FileChannel out = null;
			try {
				fi = new FileInputStream(source);
				fo = new FileOutputStream(orgFile);
				in = fi.getChannel();
				out = fo.getChannel();
				in.transferTo(0, in.size(), out);

				fi.close();
				in.close();
				fo.close();
				out.close();
			} catch (IOException e) {
				
			}
			//source.delete();
			//cutSource.delete();
		}
		ret.put("org", savePath+fileName.replace(".", "_org."));
		return ret;
	}
    
}
